﻿using DBUtil.Attributes;
using DotNetCommon.Extensions;
using NUnit.Framework;
using Shouldly;
using System.ComponentModel.DataAnnotations.Schema;

namespace Test.MySql.JsonTests.Primitives
{
    [TestFixture]
    internal class SimpleTypeTests_bool : TestBase
    {
        #region model
        [Table("test_nokey")]
        public class PersonNoKey
        {
            [PrimaryKey(KeyStrategy = KeyStrategy.Identity)]
            [Column("id")]
            public int Id { get; set; }

            [JsonStore(Bucket = "p_bool")]
            public bool p_bool { get; set; }
            [JsonStore(Bucket = "p_bool_null")]
            public bool? p_bool_null { get; set; }
        }
        [Table("test_withkey")]
        public class PersonWithKey
        {
            [PrimaryKey(KeyStrategy = KeyStrategy.Identity)]
            [Column("id")]
            public int Id { get; set; }

            [JsonStore(Bucket = "ext", Key = "p_bool")]
            public bool p_bool { get; set; }
            [JsonStore(Bucket = "ext", Key = "p_bool_null")]
            public bool? p_bool_null { get; set; }
        }
        #endregion

        [SetUp]
        public void SetUp()
        {
            DropTableIfExist("test_nokey");
            db.ExecuteSql("""
                create table test_nokey(id int auto_increment primary key,p_bool json,p_bool_null json)
                """);
            db.Insert<PersonNoKey>().SetEntity([
                new PersonNoKey{p_bool=true,p_bool_null=true,},
                new PersonNoKey{p_bool=false,p_bool_null=null,}
            ]).ExecuteAffrows();
            var json = db.Select<PersonNoKey>().ToList().ToJson();
            json.ShouldBe("""[{"Id":1,"p_bool":true,"p_bool_null":true},{"Id":2,"p_bool":false,"p_bool_null":null}]""");


            DropTableIfExist("test_withkey");
            db.ExecuteSql("""
                create table test_withkey(id int auto_increment primary key,ext json)
                """);
            db.Insert<PersonWithKey>().SetEntity([
                new PersonWithKey{p_bool=true,p_bool_null=true,},
                new PersonWithKey{p_bool=false,p_bool_null=null,}
            ]).ExecuteAffrows();
            var json2 = db.Select<PersonWithKey>().ToList().ToJson();
            json2.ShouldBe("""[{"Id":1,"p_bool":true,"p_bool_null":true},{"Id":2,"p_bool":false,"p_bool_null":null}]""");
        }

        #region NoKey
        [Test]
        public void TestInsert_ByEntity()
        {
            //不用测 setup 里就是
        }

        [Test]
        public void TestInsert_BySet()
        {
            //先清除数据
            db.ExecuteSql(db.Manage.TruncateTableSql(db.TableSeg<PersonNoKey>()));

            //set 值
            db.Insert<PersonNoKey>()
                .SetColumnExpr(i => i.p_bool, true)
                .SetColumnExpr(i => i.p_bool_null, true)
                .ExecuteAffrows();

            db.Insert<PersonNoKey>()
                .SetColumnExpr(i => i.p_bool, false)
                .SetColumnExpr(i => i.p_bool_null, null)
                .ExecuteAffrows();

            //set 属性名
            db.Insert<PersonNoKey>()
                .SetColumn(db.GetColumnName(typeof(PersonNoKey), nameof(PersonNoKey.p_bool)), true)
                .SetColumn(nameof(PersonNoKey.p_bool_null), true)
                .ExecuteAffrows();

            db.Insert<PersonNoKey>()
                .SetColumn(nameof(PersonNoKey.p_bool), () => false)
                .SetColumn(nameof(PersonNoKey.p_bool_null), null)
                .ExecuteAffrows();

            //
            var list = db.Select<PersonNoKey>().ToList();
            var json = list.ToJson();
        }

        [Test]
        public void TestUpdate()
        {
            var update = db.Update<PersonNoKey>().SetEntity(new PersonNoKey { Id = 2, p_bool = true, p_bool_null = false, });
            var r = update.ExecuteAffrows();
            r.ShouldBe(1);
            var person = db.Select<PersonNoKey>().Where(i => i.Id == 2).FirstOrDefault();
            var json = person.ToJson();
            json.ShouldBe("""{"Id":2,"p_bool":true,"p_bool_null":false}""");
        }

        [Test]
        public void TestSelect()
        {
            var select = db.Select<PersonNoKey>().Where(i => i.p_bool == false && i.p_bool_null == null);
            var list = select.ToList();
            var json = list.ToJson();
            json.ShouldBe("""[{"Id":2,"p_bool":false,"p_bool_null":null}]""");
        }
        #endregion

        #region Key
        [Test]
        public void TestInsertKey()
        {
            var insert = db.Insert<PersonWithKey>().SetEntity([
                new PersonWithKey{p_bool=true,p_bool_null=true,},
                new PersonWithKey{p_bool=false,p_bool_null=null,}
            ]);
            var r = insert.ExecuteAffrows();
            r.ShouldBe(2);
            var list = insert.ExecuteInsertedList();
            var json = list.ToJson();
            json.ShouldBe("""[{"Id":5,"p_bool":true,"p_bool_null":true},{"Id":6,"p_bool":false,"p_bool_null":null}]""");
        }

        [Test]
        public void TestUpdateKey()
        {
            var update = db.Update<PersonWithKey>().SetEntity(new PersonWithKey { Id = 2, p_bool = true, p_bool_null = false, });
            var r = update.ExecuteAffrows();
            r.ShouldBe(1);
            var person = db.Select<PersonWithKey>().Where(i => i.Id == 2).FirstOrDefault();
            var json = person.ToJson();
            json.ShouldBe("""{"Id":2,"p_bool":true,"p_bool_null":false}""");
        }

        [Test]
        public void TestSelectKey()
        {
            var select = db.Select<PersonWithKey>().Where(i => i.p_bool == false && i.p_bool_null == null);
            var list = select.ToList();
            var json = list.ToJson();
            json.ShouldBe("""[{"Id":2,"p_bool":false,"p_bool_null":null}]""");
        }
        #endregion
    }
}
